package xin.qixia.robot.core.factory;

import xin.qixia.robot.core.client.RobotClient;
import xin.qixia.robot.core.domain.Robot;
import xin.qixia.robot.core.domain.RobotMessage;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 机器人客户端工厂
 *
 * @author wangkaixin
 * @date 2025/5/26 14:47
 */
public class RobotClientFactory {

    /**
     * 类型和客户端的对应关系
     */
    private final Map<String, RobotClient> clientMap = new ConcurrentHashMap<>();

    /**
     * 账号和客户端的对应关系
     */
    private final Map<String, Robot> accountMap = new ConcurrentHashMap<>();

    /**
     * 根据类型初始化客户端
     *
     * @param clients
     */
    public RobotClientFactory(List<RobotClient> clients) {
        for (RobotClient client : clients) {
            clientMap.put(client.getType(), client);
        }
    }

    /**
     * 根据类型获取客户端
     *
     * @param type
     * @return
     */
    public RobotClient getClient(String type) {
        return Optional.ofNullable(clientMap.get(type))
                .orElseThrow(() -> new IllegalArgumentException("不支持的机器人类型: " + type));
    }

    /**
     * 根据账号获取客户端
     *
     * @param account
     * @return
     */
    public RobotClient getClientByAccount(String account) {
        return Optional.ofNullable(clientMap.get(accountMap.get(account).getType()))
                .orElseThrow(() -> new IllegalArgumentException("该机器人账号未注册: " + account));
    }

    /**
     * 注册机器人
     *
     * @param robot
     * @return
     */
    public Robot register(Robot robot) {
        accountMap.put(robot.getAccount(), robot);
        return getClient(robot.getType()).register(robot);
    }

    /**
     * 注销机器人
     *
     * @param account
     */
    public Boolean cancel(String account) {
        Boolean result = getClientByAccount(account).cancel(account);
        accountMap.remove(account);
        return result;
    }

    /**
     * 发送消息
     *
     * @param message
     * @return
     */
    public Boolean send(RobotMessage message) {
        return getClientByAccount(message.getAccount()).send(message);
    }
}
